﻿using Kimd.Common;
using Kimd.Communication;
using Kimd.Logic;
using Kimd.Machine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkStation.Common;

namespace WorkStation.Logic
{
    public class PLCStatusLogic : FlowBase
    {
        private PLCOperator _plc;
        //plc通信读地址
        public const int PLC_COM_READ_ADDRESS = 410;
        public const int PLC_COM_READ_WARN_ADDRESS_START = 600;
        //plc通信写地址
        public const int PLC_COM_WRITE_ADDRESS = 500;
        private bool[] inStatus = null;
        private bool[] outStatus = new bool[30];
        private short[] vals = null;
        public PLCStatusLogic(string flowName, FlowManager flowmanager) 
            : base(flowName, flowmanager)
        {
            //_plc = MachineResource.Instance.MachinePLC["轨道PLC"];
            
        }
        public override void Home()
        {
            base.Home();
        }
        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }
        public override void Method()
        {
            if (isSimulate)
                return;

            if (false)
            {
                if (_plc != null)
                {
                    if (!_plc.IsOpenFlag)
                    {
                    reconnect:
                        lock (GlobalVariable.ConveyorPLCLock)
                        {
                            _plc.Connect();
                        }
                        if (!_plc.IsOpenFlag)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Warn, $"[{_plc.Name}]连接失败!", this.Description, 7, "轨道"));
                            //出错，停下所有线程
                            _flowManager.Pause();
                            //若为报错，需重新检测启动信号
                            WaitForStart();
                            if (!CheckFlowCondition()) return;
                            goto reconnect;
                        }
                    }
                    lock (GlobalVariable.ConveyorPLCLock)
                    {
                        while (!ReadPLC(_plc, RegisterType.M, PLC_COM_READ_ADDRESS, 20, out inStatus))
                        {
                            System.Threading.Thread.Sleep(20);
                        }
                    }
                    if (inStatus != null)
                    {
                        for (int i = 0; i < inStatus.Length; i++)
                        {
                            GlobalVariable.PCReadPLCData[i] = inStatus[i];
                        }
                    }
                    System.Threading.Thread.Sleep(100);
                    lock (GlobalVariable.ConveyorPLCLock)
                    {
                        while (!ReadPLC(_plc, RegisterType.D, 0, out GlobalVariable.PLCStatusData))
                        {
                            Thread.Sleep(40);
                        }
                    }
                    for (int i = 0; i < GlobalVariable.PCWritePLCData.Length; i++)
                    {
                        outStatus[i] = GlobalVariable.PCWritePLCData[i];
                    }
                    lock (GlobalVariable.ConveyorPLCLock)
                    {
                        while (!WriteLC(_plc, RegisterType.M, PLC_COM_WRITE_ADDRESS, 30, outStatus))
                        {
                            System.Threading.Thread.Sleep(20);
                        }
                    }

                    Thread.Sleep(100);
                }
            }
            else
            {
                if(GlobalVariable.ConveyorPLC == null)
                {
                    GlobalVariable.ConveyorPLC = new ModbusTcp("192.168.10.31", 502);
                    GlobalVariable.ConveyorPLC.Connect();
                }
                if (GlobalVariable.ConveyorPLC.IsConnected)
                {
                    GlobalVariable.ConveyorPLC.ReadBool("410", 20, out inStatus);
                    if (inStatus != null)
                    {
                        for (int i = 0; i < inStatus.Length; i++)
                        {
                            GlobalVariable.PCReadPLCData[i] = inStatus[i];
                        }
                    }
                    System.Threading.Thread.Sleep(100);

                    GlobalVariable.ConveyorPLC.ReadShort("0", 1, out short[] a);
                    GlobalVariable.PLCStatusData = a[0];

                    for (int i = 0; i < GlobalVariable.PCWritePLCData.Length; i++)
                    {
                        outStatus[i] = GlobalVariable.PCWritePLCData[i];
                    }
                    GlobalVariable.ConveyorPLC.WriteBool("500", outStatus);

                    Thread.Sleep(100);
                }
            }
        }
        public override void OnStop()
        {
            base.OnStop();
        } 
        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }
    }
    public enum PLCOutFlag
    {
        [Description("轨道手动自动切换")]
        ConveyorAutoManual = 0,
        [Description("轨道自动启动")]
        ConveyorAutoStart,
        [Description("轨道停止")]
        ConveyorStop,
        [Description("轨道回零启动")]
        ConveyorHomeStart,
        [Description("清除轨道故障")]
        ClearConveyorErr,
        [Description("人工放置满Tray")]
        ManualPutFullTray,
        [Description("需上料满Tray")]
        NeedFeedFullTray=10,
        [Description("取上料满Tray完成")]
        GetFullTrayFinish,
        [Description("需上料满Tray2")]
        NeedFeedFullTray2,
        [Description("取上料满Tray完成2")]
        GetFullTrayFinish2,
        [Description("需下料空Tray")]
        NeedEmptyTray = 20,
        [Description("放下料空Tray完成")]
        PutEmptyTrayFinish,
        [Description("需下料空Tray2")]
        NeedEmptyTray2,
        [Description("放下料空Tray完成2")]
        PutEmptyTrayFinish2,
        [Description("CarrierCheck成功")]
        CarrierCheck成功,
        [Description("CarrierCheck失败")]
        CarrierCheck失败,
    }
    public enum PLCInFlag
    {
        [Description("允许取上料满Tray")]
        AllowGetFeedTray,
        [Description("下空Tray完成")]
        EmptyTrayDownFinish,
        [Description("允许取上料满Tray2")]
        AllowGetFeedTray2,
        [Description("下空Tray完成2")]
        EmptyTrayDownFinish2,
        [Description("允许放下料空Tray")]
        AllowPutUnloadTray = 10,
        [Description("下满Tray完成")]
        FullTrayDownFinish,
        [Description("允许放下料空Tray2")]
        AllowPutUnloadTray2,
        [Description("下满Tray完成2")]
        FullTrayDownFinish2,
        [Description("Boat请求扫码")]
        Boat请求扫码,
        [Description("Boat扫码失败")]
        Boat扫码失败,
        [Description("轨道PLC报警")]
        轨道PLC报警,
        //[Description("请求息屏")]
        //AskCloseMonitor,
        //[Description("当前模式")]
        //CurrentMode = 6,
    }
    public enum PLCWarnCode
    {
        [Description("料仓缺料警告!")]
        料仓缺料警告,
        [Description("下料移动轴正限触发!")]
        下料移动轴正限触发,
        [Description("下料移动轴负限触发!")]
        下料移动轴负限触发,
        [Description("线体1上料顶升轴负限触发!")]
        线体1上料顶升轴负限触发,
        [Description("线体1上料顶升轴正限触发!")]
        线体1上料顶升轴正限触发,
        [Description("线体1下料顶升轴负限触发!")]
        线体1下料顶升轴负限触发,
        [Description("线体1下料顶升轴正限触发!")]
        线体1下料顶升轴正限触发,
        [Description("线体2下料顶升轴负限触发!")]
        线体2下料顶升轴负限触发,
        [Description("线体2下料顶升轴正限触发!")]
        线体2下料顶升轴正限触发,
        [Description("料仓顶升轴负限触发!")]
        料仓顶升轴负限触发,
        [Description("料仓顶升轴正限触发!")]
        料仓顶升轴正限触发,
    }
    public enum PLCErrorCode
    {
        [Description("EtherCAT网络错误!")]
        EtherCAT网络错误 = 2,
        [Description("下料移动轴错误!")]
        下料移动轴错误 = 10,
        [Description("线体1上料顶升轴错误!")]
        线体1上料顶升轴错误,
        [Description("线体1下料顶升轴错误!")]
        线体1下料顶升轴错误,
        [Description("线体2下料顶升轴错误!")]
        线体2下料顶升轴错误,
        [Description("料仓顶升轴错误!")]
        料仓顶升轴错误,
        [Description("线体1流线轴错误!")]
        线体1流线轴错误,
        [Description("线体2流线轴错误!")]
        线体2流线轴错误,
        [Description("线体1扫码区顶升气缸下位故障!")]
        线体1扫码区顶升气缸下位故障 = 20,
        [Description("线体1扫码区顶升气缸上位故障!")]
        线体1扫码区顶升气缸上位故障,
        [Description("线体1扫码区阻挡气缸上位故障!")]
        线体1扫码区阻挡气缸上位故障,
        [Description("线体1扫码区阻挡气缸下位故障!")]
        线体1扫码区阻挡气缸下位故障,
        [Description("线体1上料区阻挡气缸上位故障!")]
        线体1上料区阻挡气缸上位故障,
        [Description("线体1上料区阻挡气缸下位故障!")]
        线体1上料区阻挡气缸下位故障,
        [Description("上料区侧夹气缸伸出故障!")]
        上料区侧夹气缸伸出故障,
        [Description("上料区侧夹气缸缩回故障!")]
        上料区侧夹气缸缩回故障,
        [Description("线体1空Tray区阻挡气缸上位故障!")]
        线体1空Tray区阻挡气缸上位故障,
        [Description("线体1空Tray区阻挡气缸下位故障!")]
        线体1空Tray区阻挡气缸下位故障,
        [Description("空Tray区侧夹气缸伸出故障!")]
        空Tray区侧夹气缸伸出故障,
        [Description("空Tray区侧夹气缸缩回故障!")]
        空Tray区侧夹气缸缩回故障,
        [Description("线体1空Tray区长顶升气缸下位故障!")]
        线体1空Tray区长顶升气缸下位故障,
        [Description("线体1空Tray区长顶升气缸上位故障!")]
        线体1空Tray区长顶升气缸上位故障,
        [Description("线体1空Tray区短顶升气缸下位故障!")]
        线体1空Tray区短顶升气缸下位故障,
        [Description("线体1空Tray区短顶升气缸上位故障!")]
        线体1空Tray区短顶升气缸上位故障,
        [Description("线体1下料区阻挡气缸上位故障!")]
        线体1下料区阻挡气缸上位故障,
        [Description("线体1下料区阻挡气缸下位故障!")]
        线体1下料区阻挡气缸下位故障,
        [Description("下料区侧推气缸缩回故障!")]
        下料区侧推气缸缩回故障,
        [Description("下料区侧推气缸伸出故障!")]
        下料区侧推气缸伸出故障,
        [Description("下料区侧夹气缸伸出故障!")]
        下料区侧夹气缸伸出故障,
        [Description("下料区侧夹气缸缩回故障!")]
        下料区侧夹气缸缩回故障,
        [Description("料仓侧夹气缸伸出故障!")]
        料仓侧夹气缸伸出故障 = 46,
        [Description("料仓侧夹气缸缩回故障!")]
        料仓侧夹气缸缩回故障,
        [Description("下料料仓侧夹气缸伸出故障!")]
        下料料仓侧夹气缸伸出故障,
        [Description("下料料仓侧夹气缸缩回故障!")]
        下料料仓侧夹气缸缩回故障,
        [Description("下料料仓阻挡气缸上位故障!")]
        下料料仓阻挡气缸上位故障,
        [Description("下料料仓阻挡气缸下位故障!")]
        下料料仓阻挡气缸下位故障,
        [Description("线体1扫码区入料超时!")]
        线体1扫码区入料超时 = 60,
        [Description("线体1上料区入料超时!")]
        线体1上料区入料超时,
        [Description("线体1上料区顶升上料失败!")]
        线体1上料区顶升上料失败,
        [Description("线体1上料区顶升下料失败!")]
        线体1上料区顶升下料失败,
        [Description("人工取上料Tray失败!")]
        人工取上料Tray失败,
        [Description("线体1空Tray区入料失败!")]
        线体1空Tray区入料失败,
        [Description("线体1空Tray区顶升上料失败!")]
        线体1空Tray区顶升上料失败,
        [Description("线体1空Tray区顶升下料失败!")]
        线体1空Tray区顶升下料失败,
        [Description("线体1下料区入料失败!")]
        线体1下料区入料失败,
        [Description("线体1下料区顶升上料失败!")]
        线体1下料区顶升上料失败,
        [Description("人工取下料Tray失败!")]
        人工取下料Tray失败,
        [Description("线体2顶升到位没感应到Tray!")]
        线体2顶升到位没感应到Tray,
        [Description("线体2入料区入料超时!")]
        线体2入料区入料超时,
        [Description("线体2出料区顶升有料,请取走!")]
        线体2出料区顶升有料,
        [Description("线体2出料口长时间没感应到Tray!")]
        线体2出料口长时间没感应到Tray,
    }
}
